package com.yuxi.config;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.github.pagehelper.PageHelper;
import com.yuxi.auto.TableSegInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * mybatis 配置文件 多数据源的配置方法
 * Created by yuxi on 16/10/25.
 */

@Configuration    //该注解类似于spring配置文件
@MapperScan(basePackages = "com.yuxi.mapper")
@PropertySource("classpath:application.properties")
public class DataSourceConfig implements EnvironmentAware {


    /*****
     *配置多数据源的步骤
     * 1 定义多个数据源的枚举
     * 2 定义一个线程安全的类可以获取和设置数据源
     * 3 继承动态配置数据源的AbstractRoutingDataSource
     * 4 在配置文件,配置两份数据源,设置动态数据源
     * 5 根据动态数据源创建SqlSessionFactory
     * 6 根据动态数据源配置事务
     */



    private Environment env;
    @Override
    public void setEnvironment(Environment environment) {
        this.env=environment;
    }


    /**
     * 读取数据库配置文件1
     *
     * @return
     * @throws Exception
     */
    @Bean
    public DataSource getDataSource1() throws Exception {
        Properties props = new Properties();
        props.put("driverClassName", env.getProperty("jdbc.driverClassName"));
        props.put("url", env.getProperty("jdbc.url"));
        props.put("username", env.getProperty("jdbc.username"));
        props.put("password", env.getProperty("jdbc.password"));
        props.put("maxActive", env.getProperty("jdbc.maxActive"));
        return DruidDataSourceFactory.createDataSource(props);
    }

//    /**
//     * 读取数据库配置文件2
//     *
//     * @return
//     * @throws Exception
//     */
//    @Bean
//    public DataSource getDataSource2() throws Exception {
//        Properties props = new Properties();
//        props.put("driverClassName", env.getProperty("jdbc2.driverClassName"));
//        props.put("url", env.getProperty("jdbc2.url"));
//        props.put("username", env.getProperty("jdbc2.username"));
//        props.put("password", env.getProperty("jdbc2.password"));
//        return DruidDataSourceFactory.createDataSource(props);
//    }
//
//
//    /**
//     * * @Primary 该注解表示在同一个接口有多个实现类可以注入的时候，默认选择哪一个，而不是让@autowire注解报错
//     * * @Qualifier 根据名称进行注入，通常是在具有相同的多个类型的实例的一个注入（例如有多个DataSource类型的实例）
//     */
//    @Bean
//    @Primary
//    public DynamicDataSource dataSource(@Qualifier("getDataSource1") DataSource jiuye,
//                                        @Qualifier("getDataSource2") DataSource zhuxue) {
//        Map<Object, Object> targetDataSources = new HashMap<>();
//        targetDataSources.put(DataType.JIUYE, jiuye);
//        targetDataSources.put(DataType.ZHUXUE, zhuxue);
//
//        DynamicDataSource dataSource = new DynamicDataSource();
//        dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法
//        dataSource.setDefaultTargetDataSource(jiuye);// 默认的datasource设置为myTestDbDataSource
//
//        return dataSource;
//    }


//    /**
//     * 根据数据源创建SqlSessionFactory,读取配置文件
//     */
//    @Bean
//    public SqlSessionFactory sqlSessionFactory(DynamicDataSource ds) throws Exception {
//        SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
//        fb.setDataSource(ds);//指定数据源(这个必须有，否则报错)
//
//
//        //分页插件
//        PageHelper pageHelper = new PageHelper();
//        Properties properties = new Properties();
//        properties.setProperty("reasonable", "true");
//        properties.setProperty("supportMethodsArguments", "true");
//        properties.setProperty("returnPageInfo", "check");
//        properties.setProperty("params", "count=countSql");
//        pageHelper.setProperties(properties);
//        //添加插件
//        fb.setPlugins(new Interceptor[]{pageHelper});
//
//
//        //下边两句仅仅用于*.xml文件，如果整个持久层操作不需要使用到xml文件的话（只用注解就可以搞定），则不加
//        fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage"));//指定基包
//        fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(
//                env.getProperty("mybatis.mapperLocations")));//指定xml文件位置
//        return fb.getObject();
//    }
//
//    /**
//     * 添加事务管理的配置
//     *
//     * @return
//     * @throws Exception
//     */
//    @Bean
//    @Primary
//    public DataSourceTransactionManager transactionManager(DynamicDataSource dynamicDataSource) throws Exception {
//        return new DataSourceTransactionManager(dynamicDataSource);
//    }


    /**
     * 根据数据源创建SqlSessionFactory,读取配置文件
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource ds) throws Exception {
        SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
        fb.setDataSource(ds);//指定数据源(这个必须有，否则报错)


        //分页插件
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
        properties.setProperty("reasonable", "true");
        properties.setProperty("supportMethodsArguments", "true");
        properties.setProperty("returnPageInfo", "check");
        properties.setProperty("params", "count=countSql");
        pageHelper.setProperties(properties);
        //添加插件
        fb.setPlugins(new Interceptor[]{pageHelper});


        //下边两句仅仅用于*.xml文件，如果整个持久层操作不需要使用到xml文件的话（只用注解就可以搞定），则不加
        fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage"));//指定基包
        fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(
                env.getProperty("mybatis.mapperLocations")));//指定xml文件位置



        //添加插件
        Interceptor[] interceptors = {getInstance()};
        fb.setPlugins(interceptors);
        return fb.getObject();
    }

    @Bean
    public TableSegInterceptor getInstance() {
        return new TableSegInterceptor();
    }

    /**
     * 添加事务管理的配置
     *
     * @return
     * @throws Exception
     */
    @Bean
    @Primary
    public DataSourceTransactionManager transactionManager(DataSource dataSource) throws Exception {
        return new DataSourceTransactionManager(dataSource);
    }


}
